/**
 * Copyright 2002-2010 the original author or authors.
 */
package com.apache.portal.thread;

import com.apache.uct.common.ToolsUtil;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import java.util.Random;

/**
 * 对文件的删除、剪切、移动和创建文件夹操作
 *
 * @author Hou Dayu
 */
public class FileOperateUtil {

    private static Logger log = LoggerFactory.getLogger(FileOperateUtil.class);

    /**
     * 检查文件或文件夹是否存在
     *
     * @param folderPath 文件或文件夹路径
     * @return true为存在，false不存在
     */
    public static boolean checkFolder(String folderPath) {
        boolean result = false;
        if (ToolsUtil.isNotNull(folderPath)) {
            File newFilePath = new File(folderPath);
            result = newFilePath.exists();
        }
        return result;
    }

    /**
     * 取指定文件夹中的文件的数量
     *
     * @param path 文件夹路径
     * @param fileNamePrefix 文件名前缀
     * @return
     */
    public static int getFileNumber(String path, String fileNamePrefix) {
        int fileCount = 0;
        if (ToolsUtil.isNotNull(path)) {
            File d = new File(path);
            File list[] = d.listFiles();
            for (int i = 0; i < list.length; i++) {
                if (list[i].isFile()) {
                    if (ToolsUtil.isNotNull(fileNamePrefix)) {
                        if (list[i].getName().indexOf(fileNamePrefix) != -1)
                            fileCount++;
                    } else
                        fileCount++;
                }
            }
        }
        return fileCount;
    }

    /**
     * 新建目录操作
     *
     * @param folderPath 文件夹路径
     */
    public static boolean newCreateFolder(String folderPath) {
        boolean result = false;
        try {
            if (ToolsUtil.isNotNull(folderPath)) {
                File newFilePath = new File(folderPath);
                if (!newFilePath.exists()) {
                    result = newFilePath.mkdirs();
                }
            }
        } catch (Exception e) {
            log.error("新建目录操作出错ERROR KEY:" + e.getMessage());
        }
        return result;
    }

    /**
     * 创建新的文件
     *
     * @param filePathAndName 文件名称
     * @param fileContent 文件内容
     */
    public static boolean newCreateFile(String filePathAndName, String fileContent) {
        boolean result = false;
        try {
            if (ToolsUtil.isNotNull(filePathAndName)) {
                File newFilePath = new File(filePathAndName);
                if (!newFilePath.exists()) {
                    newFilePath.createNewFile();
                }
                FileUtils.writeStringToFile(newFilePath, fileContent);
                result = true;
            }
        } catch (Exception e) {
            log.error("新建文件操作出错ERROR KEY:" + e.getMessage());
        }
        return result;
    }

    /**
     * 创建新的文件
     *
     * @param filePathAndName 文件名称
     * @param fileContent 文件内容
     */
    public static boolean newCreateFile(String filePathAndName, String fileContent,
            String encoding) {
        boolean result = false;
        try {
            if (ToolsUtil.isNotNull(filePathAndName)) {
                File newFilePath = new File(filePathAndName);
                if (!newFilePath.exists()) {
                    newFilePath.createNewFile();
                }
                FileUtils.writeStringToFile(newFilePath, fileContent, encoding);
                result = true;
            }
        } catch (Exception e) {
            log.error("新建文件操作出错ERROR KEY:" + e.getMessage());
        }
        return result;
    }

    /**
     * 创建新的文件
     *
     * @param inputStream 文件内容流
     * @param filePath 文件路径
     * @return 返回true为创建成功，false为创建失败
     */
    public static boolean newCreateFile(InputStream inputStream, String filePath) {
        boolean result = false;
        if (inputStream == null)
            return false;
        FileOutputStream output = null;
        try {
            if (checkFolder(filePath))
                delFile(filePath);
            output = new FileOutputStream(filePath);
            byte[] buffer = new byte[1024];
            int bytesRead = 0;

            while ((bytesRead = inputStream.read(buffer, 0, 1024)) != -1) {
                output.write(buffer, 0, bytesRead);
            }
            result = true;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            log.error("新建文件操作出错ERROR KEY:" + e.getMessage());
        } catch (IOException e) {
            e.printStackTrace();
            log.error("新建文件操作出错ERROR KEY:" + e.getMessage());
        } finally {
            IOUtils.closeQuietly(output);
            IOUtils.closeQuietly(inputStream);
        }
        return result;
    }

    /**
     * 删除文件
     *
     * @param filePathAndName 文件路径名称
     * @return true删除成功，false删除失败
     */
    public static boolean delFile(String filePathAndName) {
        boolean result = false;
        try {
            if (ToolsUtil.isNotNull(filePathAndName)) {
                if (checkFolder(filePathAndName)) {
                    File delFile = new File(filePathAndName);
                    result = delFile.delete();
                }
                result = true;
            }
        } catch (Exception e) {
            log.error("删除文件操作出错ERROR KEY:" + e.getMessage());
        }
        return result;
    }

    /**
     * 删除文件夹
     *
     * @param folderPath 文件夹路径
     * @param isDelFolderPath 是否删除文件夹目录。
     * @return true删除，false不删除。
     */
    public static void delFolder(String folderPath, boolean isDelFolderPath) {
        try {
            if (ToolsUtil.isNotNull(folderPath)) {
                delAllFile(folderPath);//删除完里面所有内容
                if (isDelFolderPath) {
                    File delFilePath = new File(folderPath);
                    delFilePath.delete(); //删除空文件夹
                }
            }
        } catch (Exception e) {
            log.error("删除文件夹操作出错ERROR KEY:" + e.getMessage());
        }
    }

    /**
     * 批量删除文件
     *
     * @param path 文件所在目录
     * @return true删除成功，false删除失败
     */
    public static boolean delAllFile(String path) {
        if (ToolsUtil.isNull(path))
            return false;
        File file = new File(path);
        if (!file.exists()) {
            return false;
        }
        if (!file.isDirectory()) {
            return false;
        }
        String[] tempList = file.list();
        File temp = null;
        for (int i = 0; i < tempList.length; i++) {
            if (path.endsWith(File.separator)) {
                temp = new File(path + tempList[i]);
            } else {
                temp = new File(path + File.separator + tempList[i]);
            }
            if (temp.isFile()) {
                temp.delete();
            }
            if (temp.isDirectory()) {
                //删除文件夹里面的文件
                delAllFile(path + "/" + tempList[i]);
                delFolder(path + "/" + tempList[i], true);//删除空文件夹
            }
        }
        return true;
    }

    /**
     * 删除文件夹
     *
     * @param folderPath 文件夹路径
     * @return 返回删除成功和失败的数量集合
     */
    public static Map<String, String> delFolder(String folderPath, Map<String, String> map) {
        try {
            if (ToolsUtil.isNotNull(folderPath)) {
                map = delAllFile(folderPath, map);//删除完里面所有内容
                File delFilePath = new File(folderPath);
                delFilePath.delete(); //删除空文件夹
            }
        } catch (Exception e) {
            log.error("删除文件夹操作出错ERROR KEY:" + e.getMessage());
        }
        if (ToolsUtil.isEmpty(map))
            map = new HashMap<String, String>();
        return map;
    }

    /**
     * 批量删除文件
     *
     * @param path 文件所在目录
     * @param map 删除成功和失败的数量集合
     * @return 返回删除成功和失败的数量集合
     */
    public static Map<String, String> delAllFile(String path, Map<String, String> map) {
        if (ToolsUtil.isNull(path))
            return null;
        File file = new File(path);
        if (!file.exists()) {
            return null;
        }
        if (!file.isDirectory()) {
            return null;
        }
        String[] tempList = file.list();
        File temp = null;
        for (int i = 0; i < tempList.length; i++) {
            if (path.endsWith(File.separator)) {
                temp = new File(path + tempList[i]);
            } else {
                temp = new File(path + File.separator + tempList[i]);
            }
            map = getDelFileMap(temp, map);
            if (temp.isDirectory()) {
                //删除文件夹里面的文件
                map = delAllFile(path + "/" + tempList[i], map);
                map = delFolder(path + "/" + tempList[i], map);//删除空文件夹
            }
        }
        return map;
    }

    /**
     * 复制文件到指定目录
     *
     * @param oldPath 源路径
     * @param newPath 新路径
     * @return true复制成功，false复制失败
     */
    public static boolean copyFile(String oldPath, String newPath) {
        boolean result = false;
        try {
            if (ToolsUtil.isNotNull(oldPath) && ToolsUtil.isNotNull(newPath)) {

                //统一配置后，两个path一样，所以屏蔽要复制的文件与原文件属于同一个父节点错误
                if (oldPath.equalsIgnoreCase(newPath)) {
                    return true;
                }
                File oldfile = new File(oldPath);
                if (oldfile.exists()) { //文件存在时
                    FileUtils.copyFile(oldfile, new File(newPath));
                }
                result = true;
            }
        } catch (Exception e) {
            log.error("复制文件操作出错ERROR KEY:" + e.getMessage());
        }
        return result;
    }

    /**
     * 复制整个文件夹及内容
     *
     * @param oldPath 源路径
     * @param newPath 新路径
     * @param type 不需要复制的文件（如html,jsp,asp,shtml,htm...）
     */
    public static void copyFolder(String oldPath, String newPath, String type) {
        try {
            if (ToolsUtil.isNotNull(oldPath) && ToolsUtil.isNotNull(newPath)) {
                if (oldPath.equalsIgnoreCase(newPath)) {
                    return;
                }
                newCreateFolder(newPath);//如果文件夹不存在 则建立新文件夹
                File oldFilePath = new File(oldPath);
                FileUtils.copyDirectory(oldFilePath, new File(newPath), true);
            }
        } catch (Exception e) {
            log.error("复制整个文件夹内容操作出错 ERROR KEY:" + e.getMessage());
        }
    }

    /**
     * 复制整个文件夹及内容
     *
     * @param filePath 源文件存放地址
     * @param newFilePath 复制后存放的地址
     */
    public static void copyFiles(String filePath, String newFilePath) {
        if (ToolsUtil.isNotNull(filePath) && ToolsUtil.isNotNull(newFilePath)) {
            //统一配置后，两个path一样，所以屏蔽要复制的文件与原文件属于同一个父节点错误
            if (filePath.equalsIgnoreCase(newFilePath)) {
                return;
            }

            LinkedList<File> list = new LinkedList<File>();
            Map<String, String> filePaths = new HashMap<String, String>();
            newCreateFolder(filePath);
            File file = new File(filePath);
            if (file.exists()) {
                newCreateFolder(newFilePath);
                if (file.isDirectory()) {
                    File[] fileArray = file.listFiles();
                    if (!ToolsUtil.isNull(fileArray)) {
                        for (int i = 0; i < fileArray.length; i++) {
                            if (fileArray[i].isDirectory()) {
                                String path = newFilePath + "/" + fileArray[i].getName();
                                newCreateFolder(path);
                                filePaths.put(fileArray[i].getPath(), path);
                                list.add(fileArray[i]);
                            } else {
                                copyFile(fileArray[i].toString(),
                                        newFilePath + "/" + fileArray[i].getName().toString());
                            }
                        }
                    }
                    copyFiles(filePaths, list);
                } else
                    copyFile(file.toString(), newFilePath + "/" + file.getName().toString());
            } else
                log.error("The File/Folder doesn't exist!");
        }
    }

    /**
     * 如果folderPath为文件路径，则将该文件变成一个空文件。<br>
     * 如果folderPath是文件夹路径，则将其下的所有文件都变成空文件。
     *
     * @param folderPath 文件或文件夹的绝对路径
     */
    public static void fileToEmpty(String folderPath) {
        LinkedList<File> list = new LinkedList<File>();
        File file = new File(folderPath);
        if (file.exists()) {
            if (file.isDirectory()) {
                File[] fileArray = file.listFiles();
                if (!ToolsUtil.isNull(fileArray)) {
                    for (int i = 0; i < fileArray.length; i++) {
                        if (fileArray[i].isDirectory()) {
                            list.add(fileArray[i]);
                        } else {
                            fileArray[i].delete();
                            newCreateFile(fileArray[i].getPath(), "");
                        }
                    }
                }
                fileToEmpty(list);
            } else {
                file.delete();
                newCreateFile(folderPath, "");
            }
        } else
            log.error("The File/Folder doesn't exist!");
    }

    /**
     * 取目录文件个数
     *
     * @param f 文件目录
     * @return 返回指定目录中文件的个数
     */
    public static long getlist(File f) {
        long size = 0;
        File flist[] = f.listFiles();
        size = flist.length;
        for (int i = 0; i < flist.length; i++) {
            if (flist[i].isDirectory()) {
                size--;
            }
        }
        return size;
    }

    /**
     * 移动文件
     *
     * @param oldPath 源路径
     * @param newPath 目标路径
     */
    public static void moveFile(String oldPath, String newPath) {
        copyFile(oldPath, newPath);
        delFile(oldPath);

    }

    /**
     * 移动文件夹及文件
     *
     * @param oldPath 源路径
     * @param newPath 目标路径
     * @param isOldPath 是否删除源路径
     */
    public static void moveFolder(String oldPath, String newPath, boolean isOldPath) {
        copyFiles(oldPath, newPath);
        delFolder(oldPath, isOldPath);
    }

    /**
     * 内容页上一页，下一页字符串生成方法
     *
     * @param savePath 文件保存路径
     * @param fileName 文件名子
     * @param content 方件内容
     */
    public static void WriteJs(String savePath, String fileName, String content) {
        newCreateFolder(savePath);
        FileOutputStream fo = null;
        PrintWriter out1 = null;
        OutputStreamWriter osw = null;
        try {
            fo = new FileOutputStream(savePath + fileName);//"content_page.js");
            osw = new OutputStreamWriter(fo, "UTF-8");
            out1 = new PrintWriter(osw);
            out1.println(content);
            out1.close();
            osw.close();
            fo.close();
        } catch (Exception e) {
            log.error("生成文件" + fileName + "出错ERROR KEY:" + e.getMessage());
        } finally {
            IOUtils.closeQuietly(out1);
            IOUtils.closeQuietly(osw);
            IOUtils.closeQuietly(fo);
        }
    }

    /**
     * 修改内容页上一页，下一页字符串
     *
     * @param fileName 文件名子
     */
    public static String getContentManager(String fileName) throws Exception {
        File file = new File(fileName);
        if (file.exists())
            return FileUtils.readFileToString(new File(fileName), "UTF-8");
        else
            return "";
    }

    /**
     * 修改Property文件
     *
     * @param pathName 文件全路径
     * @param taskId 主任务ID
     * @param resourcePath 要写入的值
     * @param isfalg true为新增内容，false为清楚内容
     * @param key property的KEY的名称
     */
    public static void removePropertyContent(String pathName, String taskId, String resourcePath,
            boolean isfalg, String key) {
        StringBuffer result = new StringBuffer();
        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(new FileInputStream(pathName), "utf8"));
            while (br.ready()) {
                String str = br.readLine();
                if (isfalg)
                    result.append(str + "\n");
                else {//清除无用的参数
                    if (str.indexOf(taskId) == -1)
                        result.append(str + "\n");
                }
            }
            br.close();
            if (isfalg)
                result.append(key + "=" + resourcePath);
            newCreateFile(pathName, result.toString());
        } catch (Exception e) {
            log.error("property文件夹操作出错ERROR KEY:" + e.getMessage());
        } finally {
            IOUtils.closeQuietly(br);
        }
    }

    /**
     * 获取文件
     *
     * @param fileName 文件名
     * @param oldPath 源文件路径
     * @param type 要过滤的文件类型
     * @return 返回指定的文件
     */
    private static File getFile(String fileName, String oldPath, String type) {
        File temp = null;
        boolean falg = false;
        if (fileName.toUpperCase().indexOf("." + type) != -1) {
            falg = true;
        } else {
            falg = fileName.toUpperCase().indexOf(".zip") != -1;//排除指定类型的文件
        }
        if (oldPath.endsWith(File.separator)) {
            if (!falg)
                temp = new File(oldPath + fileName);
            else
                temp = null;
        } else {
            if (!falg)
                temp = new File(oldPath + File.separator + fileName);
            else
                temp = null;
        }
        return temp;
    }

    /**
     * 复制整个文件夹及内容
     *
     * @param filePaths 目标文件目录集合
     * @param list 源文件目录集合
     */
    private static void copyFiles(Map<String, String> filePaths, LinkedList<File> list) {
        while (!list.isEmpty()) {
            File fileInList = list.removeFirst();
            if (fileInList.isDirectory()) {
                File[] fileArray = fileInList.listFiles();
                if (fileArray == null)
                    return;
                for (int i = 0; i < fileArray.length; i++) {
                    if (fileArray[i].isDirectory()) {
                        //如果文件夹不存在 则建立新文件夹
                        String paths =
                                filePaths.get(fileInList.getPath()) + "/" + fileArray[i].getName();
                        newCreateFolder(paths);
                        list.add(fileArray[i]);
                        filePaths.put(fileArray[i].getPath(), paths);
                    } else {
                        copyFile(fileArray[i].toString(),
                                filePaths.get(fileInList.getPath()) + "/" + fileArray[i].getName());
                    }
                }
            }
        }
    }

    /**
     * 清空整个文件夹中的文件内容
     *
     * @param list 源文件目录集合
     */
    private static void fileToEmpty(LinkedList<File> list) {
        while (!list.isEmpty()) {
            File fileInList = list.removeFirst();
            if (fileInList.isDirectory()) {
                File[] fileArray = fileInList.listFiles();
                if (fileArray == null)
                    return;
                for (int i = 0; i < fileArray.length; i++) {
                    if (fileArray[i].isDirectory()) {
                        //如果文件夹不存在 则建立新文件夹
                        list.add(fileArray[i]);
                    } else {
                        fileArray[i].delete();
                        newCreateFile(fileArray[i].getPath(), "");
                    }
                }
            } else {
                fileInList.delete();
                newCreateFile(fileInList.getPath(), "");
            }
        }
    }

    /**
     * 获取删除文件的数量
     *
     * @param temp 文件对象
     * @param map 存储集合
     * @return 返回删除文件的数量集合
     */
    private static Map<String, String> getDelFileMap(File temp, Map<String, String> map) {
        int susNum = 0, errorNum = 0;
        if (temp.isFile()) {
            boolean falg = temp.delete();
            if (falg) {
                if (!ToolsUtil.isEmpty(map.get("susm")))
                    susNum = Integer.parseInt(map.get("susm"));
                if (temp.getName().indexOf(".html") != -1 || temp.getName().indexOf(".shtml") != -1)
                    susNum++;
                map.put("susm", String.valueOf(susNum));
            } else {
                errorNum++;
                if (!ToolsUtil.isEmpty(map.get("error")))
                    errorNum = errorNum + Integer.parseInt(map.get("error"));
                map.put("error", String.valueOf(errorNum));
            }
        }
        return map;
    }

    /**
     * 修改文件名称
     *
     * @param filePath 文件件全路径
     * @param namePrefix 新名前缀
     * @param flag true为添加对应的名称前缀,false为去掉对应的名称前缀
     * @return true为名称修改成功，false为名称修改失败
     */
    public static boolean reFileName(String filePath, String namePrefix, boolean flag) {
        boolean mark = false;
        if (ToolsUtil.isNotNull(filePath) && ToolsUtil.isNotNull(namePrefix)) {
            File file = new File(filePath);
            if (file.isFile()) {
                String fileName = file.getName();
                String path = file.getPath();
                path = path.replace(fileName, "");
                if (flag) {
                    fileName = namePrefix + "_" + fileName;
                } else {
                    fileName = fileName.replace(namePrefix + "_", "");
                }
                mark = file.renameTo(new File(path + fileName)); //改名
            }
        }
        return mark;
    }

    /**
     * 格式化文件路径
     *
     * @param path 文件路径
     * @return
     */
    public static String getFormatFilePath(String path) {
        if (ToolsUtil.isNull(path))
            return "";
        path = path.replace("\\", "/");
        return path.replace("//", "/");
    }

    /**
     * 随即生成最大值以内的随机数
     *
     * @param maxNum 设定的随即最大数值
     * @return 返回随即最大限制以内的随机值
     */
    public static String getRandomNumber(int maxNum) {
        int intRd = 0; //存放随机数
        Random rdm = new Random();
        for (int i = 0; i < maxNum; i++) {
            int randomValue = rdm.nextInt();
            if (randomValue == Integer.MIN_VALUE)
                randomValue = Integer.MAX_VALUE;
            intRd = Math.abs(randomValue) % maxNum + 1;
        }
        String num = "";
        num = String.valueOf(intRd);
        return num;
    }
}
